package service

import (
	"bloggo/bloggo"
	"bloggo/structs"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"gitee.com/chunanyong/logger"
	"gitee.com/chunanyong/zorm"
	"strconv"
)

const CacheCategory = bloggo.CacheKey + structs.TbCategoryStructTableName + ":"

//SaveTbCategoryStruct 保存
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func SaveTbCategoryStruct(ctx context.Context, tbcategorystruct *structs.TbCategoryStruct) error {

	// tbcategorystruct对象指针不能为空
	if tbcategorystruct == nil {
		return errors.New("tbcategorystruct对象指针不能为空")
	}
	//匿名函数return的error如果不为nil,事务就会回滚
	_, errSaveTbCategoryStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始

		_, errSaveTbCategoryStruct := zorm.Insert(ctx, tbcategorystruct)

		if errSaveTbCategoryStruct != nil {
			return nil, errSaveTbCategoryStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errSaveTbCategoryStruct != nil {
		errSaveTbCategoryStruct := fmt.Errorf("service.SaveTbCategoryStruct错误:%w", errSaveTbCategoryStruct)
		logger.Error(errSaveTbCategoryStruct)
		return errSaveTbCategoryStruct
	}

	return nil
}

//UpdateTbCategoryStruct 更新
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateTbCategoryStruct(ctx context.Context, tbcategorystruct *structs.TbCategoryStruct) error {

	// tbcategorystruct对象指针或主键Id不能为空
	if tbcategorystruct == nil || tbcategorystruct.Id < 1 {
		return errors.New("tbcategorystruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTbCategoryStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTbCategoryStruct := zorm.Update(ctx, tbcategorystruct)

		if errUpdateTbCategoryStruct != nil {
			return nil, errUpdateTbCategoryStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTbCategoryStruct != nil {
		errUpdateTbCategoryStruct := fmt.Errorf("service.UpdateTbCategoryStruct错误:%w", errUpdateTbCategoryStruct)
		logger.Error(errUpdateTbCategoryStruct)
		return errUpdateTbCategoryStruct
	}
	bloggo.Del(CacheCategory + strconv.Itoa(tbcategorystruct.Id))
	return nil
}

//UpdateNotZeroTbCategoryStruct 更新
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func UpdateNotZeroTbCategoryStruct(ctx context.Context, tbcategorystruct *structs.TbCategoryStruct) error {

	// tbcategorystruct对象指针或主键Id不能为空
	if tbcategorystruct == nil || (tbcategorystruct.Id) < 1 {
		return errors.New("tbcategorystruct对象指针或主键Id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errUpdateTbCategoryStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		_, errUpdateTbCategoryStruct := zorm.UpdateNotZeroValue(ctx, tbcategorystruct)

		if errUpdateTbCategoryStruct != nil {
			return nil, errUpdateTbCategoryStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errUpdateTbCategoryStruct != nil {
		errUpdateTbCategoryStruct := fmt.Errorf("service.UpdateNotZeroTbCategoryStruct错误:%w", errUpdateTbCategoryStruct)
		logger.Error(errUpdateTbCategoryStruct)
		return errUpdateTbCategoryStruct
	}
	bloggo.Del(CacheCategory + strconv.Itoa(tbcategorystruct.Id))
	return nil
}

//DeleteTbCategoryStructById 根据Id删除
//如果入参ctx中没有dbConnection,使用defaultDao开启事务并最后提交
//如果入参ctx有dbConnection且没有事务,调用dbConnection.begin()开启事务并最后提交
//如果入参ctx有dbConnection且有事务,只使用不提交,有开启方提交事务
//但是如果遇到错误或者异常,虽然不是事务的开启方,也会回滚事务,让事务尽早回滚
func DeleteTbCategoryStructById(ctx context.Context, id string) error {

	//id不能为空
	if len(id) < 1 {
		return errors.New("id不能为空")
	}

	//匿名函数return的error如果不为nil,事务就会回滚
	_, errDeleteTbCategoryStruct := zorm.Transaction(ctx, func(ctx context.Context) (interface{}, error) {

		//事务下的业务代码开始
		finder := zorm.NewDeleteFinder(structs.TbCategoryStructTableName).Append(" WHERE id=?", id)
		_, errDeleteTbCategoryStruct := zorm.UpdateFinder(ctx, finder)

		if errDeleteTbCategoryStruct != nil {
			return nil, errDeleteTbCategoryStruct
		}

		return nil, nil
		//事务下的业务代码结束

	})

	//记录错误
	if errDeleteTbCategoryStruct != nil {
		errDeleteTbCategoryStruct := fmt.Errorf("service.DeleteTbCategoryStruct错误:%w", errDeleteTbCategoryStruct)
		logger.Error(errDeleteTbCategoryStruct)
		return errDeleteTbCategoryStruct
	}
	bloggo.Del(CacheCategory + id)
	return nil
}

//FindTbCategoryStructById 根据Id查询信息
//ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTbCategoryStructById(ctx context.Context, id string) (*structs.TbCategoryStruct, error) {
	//id不能为空
	if len(id) < 1 {
		return nil, errors.New("id不能为空")
	}
	bytes, _ := bloggo.Get(CacheCategory + id)
	tbcategorystruct := structs.TbCategoryStruct{}
	err := json.Unmarshal(bytes, &tbcategorystruct)
	if err == nil {
		return &tbcategorystruct, nil
	}
	//根据Id查询
	finder := zorm.NewSelectFinder(structs.TbCategoryStructTableName).Append(" WHERE id=?", id)
	has, errFindTbCategoryStructById := zorm.QueryRow(ctx, finder, &tbcategorystruct)

	//记录错误
	if errFindTbCategoryStructById != nil {
		errFindTbCategoryStructById := fmt.Errorf("service.FindTbCategoryStructById错误:%w", errFindTbCategoryStructById)
		logger.Error(errFindTbCategoryStructById)
		return nil, errFindTbCategoryStructById
	}

	if !has {
		return nil, nil
	}
	bytes, err = json.Marshal(tbcategorystruct)
	if err == nil {
		bloggo.Set(CacheCategory+id, bytes)
	}
	return &tbcategorystruct, nil

}

//FindTbCategoryStructList 根据Finder查询列表
//ctx中如果没有dbConnection,则会使用默认的datasource进行无事务查询
func FindTbCategoryStructList(ctx context.Context, finder *zorm.Finder, page *zorm.Page) ([]structs.TbCategoryStruct, error) {

	//finder不能为空
	if finder == nil {
		return nil, errors.New("finder不能为空")
	}

	tbcategorystructList := make([]structs.TbCategoryStruct, 0)
	errFindTbCategoryStructList := zorm.Query(ctx, finder, &tbcategorystructList, page)

	//记录错误
	if errFindTbCategoryStructList != nil {
		errFindTbCategoryStructList := fmt.Errorf("service.FindTbCategoryStructList错误:%w", errFindTbCategoryStructList)
		logger.Error(errFindTbCategoryStructList)
		return nil, errFindTbCategoryStructList
	}

	return tbcategorystructList, nil
}

func FindTbCategoryStructByName(ctx context.Context, categoryName string) (*structs.TbCategoryStruct, error) {
	//id不能为空
	if len(categoryName) < 1 {
		return nil, errors.New("categoryName不能为空")
	}
	tbcategorystruct := structs.TbCategoryStruct{}
	//根据Id查询
	finder := zorm.NewSelectFinder(structs.TbCategoryStructTableName).Append(" WHERE category_name=?", categoryName)
	has, errFindTbCategoryStructById := zorm.QueryRow(ctx, finder, &tbcategorystruct)

	//记录错误
	if errFindTbCategoryStructById != nil {
		errFindTbCategoryStructById := fmt.Errorf("service.FindTbCategoryStructById错误:%w", errFindTbCategoryStructById)
		logger.Error(errFindTbCategoryStructById)
		return nil, errFindTbCategoryStructById
	}

	if !has {
		return nil, nil
	}
	return &tbcategorystruct, nil

}
